--运行上面程序还有问题的，试下这个改过的程序
-- Retro Snaker

-- Use this function to perform your initial setup
supportedOrientations(LANDSCAPE_RIGHT)
function setup()
start = 0
playing = 1
over = 2
gameState = playing
moveSpeed = 30
left = ImgButton(80,200,"Cargo Bot:Command Left")
left.clickedEvent = MoveLeft
right = ImgButton(180,200,"Cargo Bot:Command Right")
right.clickedEvent = MoveRight
down = ImgButton(130,130,"Cargo Bot:Command Grab")
down.clickedEvent = MoveDown
up = ImgButton(130,270,"Cargo Bot:Condition Any")
up.clickedEvent = MoveUp
map = {}
mapwidth = 20
mapheight = 10
for i =1,mapwidth do
map[i] = {}
for j =1, mapheight do
if i==1 or i==mapwidth or j==1 or j== mapheight then
map[i][j] =1
else map[i][j] = 0
end
end
end
snakeshape = {vec2(5,5),vec2(4,5),vec2(3,5)}
direction = vec2(1,0)
cellsize = 30
-- mapImage = image(600,300)
lootCount = 0
getLoot = false
frame = 0
lootPos = getLootPosition()
--[[
setContext(mapImage)
rectMode(CENTER)
for i=1,mapwidth do
for j=1,mapheight do
if map[i][j] == 0 then
fill(106, 111, 106, 255)
rect(i*cellsize-cellsize/2,j*cellsize-cellsize/2,cellsize)
elseif map[i][j] == 1 then
fill(233, 13, 6, 255)
rect(i*cellsize-cellsize/2,j*cellsize-cellsize/2,cellsize)
end
end
end
setContext(mapImage)
--]]
rectMode(CENTER)
spriteMode(CORNER)
displayMode(FULLSCREEN)
end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
if getLootCheck() then
getLoot = true
end
frame = (frame+1)%150
if frame%moveSpeed == 0 then
if gameState == playing then
local snakeLastPosition = snakeshape[#snakeshape]
for i = #snakeshape,2,-1 do
snakeshape[i] = snakeshape[i-1]
end
snakeshape[1] = snakeshape[1]+ direction
if getLoot then
table.insert(snakeshape,snakeLastPosition)
lootPos= getLootPosition()
getLoot = false
end
end
gameOverCheck()
end
if gameState == playing then
translate(300,200)
--[[ sprite(mapImage,0,0)
sprite("Small World:Heart",(lootPos.x-1)*cellsize,(lootPos.y-1)*cellsize,cellsize)
for i=1,#snakeshape do
if i == 1 then fill(0,255,0) else fill(255) end
rect(snakeshape[i].x*cellsize-cellsize/2,snakeshape[i].y*cellsize-cellsize/2,cellsize)
end
--]]
for i=1,mapwidth do
for j=1,mapheight do
if map[i][j] == 0 then
fill(106, 111, 106, 255)
rect(i*cellsize-cellsize/2,j*cellsize-cellsize/2,cellsize)
elseif map[i][j] == 1 then
fill(233, 13, 6, 255)
rect(i*cellsize-cellsize/2,j*cellsize-cellsize/2,cellsize)
end
end
end
sprite("Small World:Heart",(lootPos.x-1)*cellsize,(lootPos.y-1)*cellsize,cellsize)
for i=1,#snakeshape do
if i == 1 then fill(0,255,0) else fill(255) end
rect(snakeshape[i].x*cellsize-cellsize/2,snakeshape[i].y*cellsize-cellsize/2,cellsize)
end
resetMatrix()
left:draw()
right:draw()
up:draw()
down:draw()
elseif gameState == over then
fill(255)
fontSize(50)
text("Game Over", WIDTH/2,HEIGHT/2)
end
end

function touched(touch)
left:touched(touch)
right:touched(touch)
up:touched(touch)
down:touched(touch)
end
function MoveLeft()
if (snakeshape[1] +vec2(-1,0)) ~= snakeshape[2] then direction = vec2(-1,0) end
end

function MoveRight()
if (snakeshape[1] +vec2(1,0)) ~= snakeshape[2] then direction = vec2(1,0) end
end

function MoveUp()
if (snakeshape[1] +vec2(0,1)) ~= snakeshape[2] then direction = vec2(0,1) end
end

function MoveDown()
if (snakeshape[1] +vec2(0,1)) ~= snakeshape[2] then direction = vec2(0,-1) end
end

function gameOverCheck()
local gameoverFlag = false
if map[snakeshape[1].x][snakeshape[1].y] == 1 then gameoverFlag = true end
for i=2,#snakeshape do
if snakeshape[1] == snakeshape[i] then gameoverFlag = true end
end
if gameoverFlag then gameState = over end
end

function getLootPosition()
while 1 do
local x,y = math.random(2,mapwidth-1),math.random(2,mapheight-1)
local pos = vec2(x,y)
local get = true
for i,v in ipairs(snakeshape) do
if v == pos then get = false end
end
if get then return pos end
end
end

function getLootCheck()
if snakeshape[1] == lootPos then return true else return false end 
end



-- 图片按钮类
-- 作者：bk194232658
-- 版本：1.0
ImgButton = class()
function ImgButton:init(x,y,img)
self.x = x
self.y = y
self.width = nil --贴图绘制宽度
self.image = img --没按下时的图片
self.pressedImage = img --按下时的图片
self.color = color(255, 255, 255, 255) --没按下时的图片颜色
self.pressedColor = color(79, 100, 208, 255) --按下后的图片颜色
self.pressed = false --是否按下中
self.clickedEvent = nil --点击后的事件回调
self.touchid = nil --触摸事件ID
self.visible = true -- 是否可见
self.enabled = true -- 是否激活
end
function ImgButton:draw()
if self.visible == false then
return
end
pushStyle()
spriteMode(CENTER)
if self.pressed then
tint(self.pressedColor)
if self.width then
sprite(self.pressedImage,self.x,self.y,self.width)
else
sprite(self.pressedImage,self.x,self.y)
end
else
tint(self.color)
if self.width then
sprite(self.image,self.x,self.y,self.width)
else
sprite(self.image,self.x,self.y)
end
end
popStyle()
end
function ImgButton:touched(touch)
if self.visible == false or self.enabled == false then
return
end
if touch.state == ENDED and self.touchid == touch.id then
self.pressed = false
end --]]
local w,h 
if self.pressed then
w,h = spriteSize(self.pressedImage)
else
w,h = spriteSize(self.image)
end
if self.width then
h = h * self.width / w
w = self.width
end
w,h = w / 2,h / 2
if touch.x > self.x - w and touch.y > self.y - h and touch.x < self.x + w and touch.y < self.y + h then
if touch.state == BEGAN then
self.pressed = true
self.touchid = touch.id
elseif touch.state == ENDED then
self.pressed = false
self.touchid = nil
if self.clickedEvent then self.clickedEvent() end
end
end
end